// ========================================================================
// $Id: ProxyServlet.java,v 1.13 2005/08/13 00:01:28 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================

package com.googlecode.authproxy.servlets;

import org.mortbay.util.IO;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import javax.servlet.ServletConfig;
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;

import com.googlecode.authproxy.AuthProxySettings;

/**
 * Based on ProxyServlet.java (see license in file header)
 * @author Niels Bosma (niels.bosma@gmail.com)
 */
public class AuthProxyServlet extends HttpServlet
{

   private ServletContext context;

   public void init(ServletConfig config) throws ServletException
   {
      this.context = config.getServletContext();
      AuthProxySettings.getInstance().updateProxy();
   }

   protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
   {
      String realUrl = "http:/"+request.getPathInfo();

      if(request.getQueryString()!=null)
      {
         realUrl += "?" + request.getQueryString();
      }

      URL url = new URL(realUrl);

      URLConnection connection = url.openConnection();

      HttpURLConnection http = null;
      if(connection instanceof HttpURLConnection)
      {
         http = (HttpURLConnection)connection;
         http.setRequestMethod(request.getMethod());
      }

      boolean hasContent = false;

      //copy request headers:
      Enumeration headers = request.getHeaderNames();
      while(headers.hasMoreElements())
      {
         String header = (String)headers.nextElement();

         if("content-type".equals(header.toLowerCase())) hasContent = true;

         Enumeration values = request.getHeaders(header);
         while(values.hasMoreElements())
         {
            String value = (String)values.nextElement();
            if(value!=null)
            {
               connection.addRequestProperty(header, value);
            }
         }
      }

      try
      {
         connection.setDoInput(true);

         //handle input:
         if(hasContent)
         {
            InputStream proxyRequest = request.getInputStream();
            connection.setDoOutput(true);
            IO.copy(proxyRequest, connection.getOutputStream());
         }
         
         connection.connect();
      }
      catch(Exception e)
      {
         context.log("proxy", e);
      }

      InputStream proxyResponse = null;

      int code=500;
      if(http!=null)
      {
         proxyResponse = http.getErrorStream();
         code = http.getResponseCode();
         //response.setStatus(code, http.getResponseMessage());
         response.setStatus(code);
      }
      if(proxyResponse==null)
      {
         try
         {
            proxyResponse = connection.getInputStream();
         }
         catch(Exception e)
         {
            if(http!=null) proxyResponse = http.getErrorStream();
            context.log("stream", e);
         }
      }

      //copy response headers:
      int i = 0;
      String header = connection.getHeaderFieldKey(i);
      String value = connection.getHeaderField(i);
      while(header!=null||value!=null)
      {
         if(header!=null&&value!=null)
         {
            response.addHeader(header, value);
         }
         ++i;
         header = connection.getHeaderFieldKey(i);
         value = connection.getHeaderField(i);
      }

      if(proxyResponse!=null)
      {
         IO.copy(proxyResponse, response.getOutputStream());
      }

   }

}
